package com.example.myapplication.analysis

import com.example.myapplication.model.PointType
import com.example.myapplication.model.SignalType
import com.example.myapplication.model.StockPrice
import com.example.myapplication.model.TechnicalIndicators
import com.example.myapplication.model.TradingPoint
import com.example.myapplication.model.TradingSignal
import com.example.myapplication.utils.TradingTimeHelper
import java.text.SimpleDateFormat
import java.util.*
import kotlin.math.abs

/**
 * 交易信号生成器
 * 基于多指标综合分析生成高胜率买卖信号
 */
class TradingSignalGenerator(private val analyzer: TechnicalAnalyzer) {
    
    companion object {
        private fun formatTimestamp(timestamp: Long): String {
            val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA)
            return sdf.format(Date(timestamp))
        }
    }
    
    /**
     * 生成交易信号（基于真实日线数据）
     * 综合考虑趋势、动量、超买超卖等多个维度
     */
    fun generateSignal(symbol: String, prices: List<StockPrice>): TradingSignal? {
        if (prices.size < 30) return null // 日线至少需要30天数据
        
        val indicators = analyzer.calculateIndicators(prices)
        val currentPrice = prices.last().close
        
        // 计算各个维度的分数
        val trendScore = analyzeTrend(indicators, currentPrice)
        val momentumScore = analyzeMomentum(indicators)
        val overboughtOversoldScore = analyzeOverboughtOversold(indicators, currentPrice)
        val volumeScore = analyzeVolume(prices)
        val macdScore = analyzeMACD(indicators)
        
        // 综合评分（0-100）
        val totalScore = (
            trendScore * 0.3 +           // 趋势权重 30%
            momentumScore * 0.25 +       // 动量权重 25%
            overboughtOversoldScore * 0.25 + // 超买超卖权重 25%
            volumeScore * 0.1 +          // 成交量权重 10%
            macdScore * 0.1              // MACD权重 10%
        ).toInt()
        
        // 确定信号类型
        val signalType = when {
            totalScore >= 75 -> SignalType.STRONG_BUY
            totalScore >= 60 -> SignalType.BUY
            totalScore >= 40 -> SignalType.HOLD
            totalScore >= 25 -> SignalType.SELL
            else -> SignalType.STRONG_SELL
        }
        
        // 计算目标价和止损价
        val (targetPrice, stopLoss) = calculatePriceTargets(currentPrice, signalType, indicators)
        
        // 生成推荐理由
        val reason = generateReason(
            signalType, 
            trendScore, 
            momentumScore, 
            overboughtOversoldScore,
            indicators
        )
        
        // 生成指标详情
        val indicatorDetails = buildIndicatorDetails(indicators, prices)
        
        // 获取最新数据的时间戳，并调整为交易时间
        val latestDataTimestamp = prices.last().timestamp
        val tradingTimestamp = TradingTimeHelper.getNearestTradingTime(latestDataTimestamp)
        
        // 如果是当天数据，使用交易时间段内的随机时间使信号更真实
        val signalTimestamp = if (TradingTimeHelper.isSameDay(latestDataTimestamp, System.currentTimeMillis())) {
            TradingTimeHelper.getRandomTradingTime(latestDataTimestamp)
        } else {
            tradingTimestamp
        }
        
        val actionTime = TradingTimeHelper.formatTradingTime(signalTimestamp)
        
        // 确定操作价格
        val actionPrice = when {
            signalType == SignalType.STRONG_BUY || signalType == SignalType.BUY -> 
                currentPrice // 买入价格为当前价格
            signalType == SignalType.SELL || signalType == SignalType.STRONG_SELL -> 
                currentPrice // 卖出价格为当前价格
            else -> null
        }
        
        return TradingSignal(
            symbol = symbol,
            signalType = signalType,
            strength = totalScore,
            price = currentPrice,
            targetPrice = targetPrice,
            stopLoss = stopLoss,
            reason = reason,
            indicators = indicatorDetails,
            timestamp = signalTimestamp,
            signalTime = actionTime,
            actionPrice = actionPrice,
            actionTime = actionTime
        )
    }
    
    /**
     * 分析趋势（基于均线系统）
     * 返回分数：0-100
     */
    private fun analyzeTrend(indicators: TechnicalIndicators, currentPrice: Double): Double {
        var score = 50.0
        
        // MA5 > MA10 > MA20 > MA60 多头排列 +40分
        if (indicators.ma5 != null && indicators.ma10 != null && 
            indicators.ma20 != null && indicators.ma60 != null) {
            
            if (indicators.ma5 > indicators.ma10 && 
                indicators.ma10 > indicators.ma20 && 
                indicators.ma20 > indicators.ma60) {
                score += 40
            } else if (indicators.ma5 < indicators.ma10 && 
                       indicators.ma10 < indicators.ma20 && 
                       indicators.ma20 < indicators.ma60) {
                score -= 40 // 空头排列
            }
        }
        
        // 价格在MA5上方 +10分
        if (indicators.ma5 != null && currentPrice > indicators.ma5) {
            score += 10
        } else if (indicators.ma5 != null && currentPrice < indicators.ma5) {
            score -= 10
        }
        
        return score.coerceIn(0.0, 100.0)
    }
    
    /**
     * 分析动量（基于RSI和KDJ）
     * 返回分数：0-100
     */
    private fun analyzeMomentum(indicators: TechnicalIndicators): Double {
        var score = 50.0
        
        // RSI分析
        indicators.rsi?.let { rsi ->
            when {
                rsi > 70 -> score -= 20 // 超买
                rsi < 30 -> score += 20 // 超卖
                rsi in 40.0..60.0 -> score += 10 // 中性偏好
            }
        }
        
        // KDJ分析
        if (indicators.k != null && indicators.d != null && indicators.j != null) {
            // 金叉
            if (indicators.k > indicators.d && indicators.j > indicators.k) {
                score += 20
            }
            // 死叉
            else if (indicators.k < indicators.d && indicators.j < indicators.k) {
                score -= 20
            }
            
            // KDJ超卖区域（< 20）
            if (indicators.k < 20 && indicators.d < 20) {
                score += 10
            }
            // KDJ超买区域（> 80）
            else if (indicators.k > 80 && indicators.d > 80) {
                score -= 10
            }
        }
        
        return score.coerceIn(0.0, 100.0)
    }
    
    /**
     * 分析超买超卖（基于布林带和RSI）
     * 返回分数：0-100
     */
    private fun analyzeOverboughtOversold(indicators: TechnicalIndicators, currentPrice: Double): Double {
        var score = 50.0
        
        // 布林带分析
        if (indicators.bollUpper != null && indicators.bollLower != null && 
            indicators.bollMiddle != null) {
            
            val bollWidth = indicators.bollUpper - indicators.bollLower
            val position = (currentPrice - indicators.bollLower) / bollWidth
            
            when {
                position < 0.2 -> score += 25 // 接近下轨，超卖
                position > 0.8 -> score -= 25 // 接近上轨，超买
                position in 0.4..0.6 -> score += 5 // 中轨附近，相对稳定
            }
        }
        
        // RSI确认
        indicators.rsi?.let { rsi ->
            when {
                rsi < 30 -> score += 25 // 超卖确认
                rsi > 70 -> score -= 25 // 超买确认
            }
        }
        
        return score.coerceIn(0.0, 100.0)
    }
    
    /**
     * 分析成交量
     * 返回分数：0-100
     */
    private fun analyzeVolume(prices: List<StockPrice>): Double {
        var score = 50.0
        
        if (prices.size < 10) return score
        
        val currentVolume = prices.last().volume.toDouble()
        val avgVolume = prices.takeLast(10).map { it.volume.toDouble() }.average()
        
        val volumeRatio = currentVolume / avgVolume
        
        // 放量配合上涨是好信号
        val priceChange = (prices.last().close - prices[prices.size - 2].close) / prices[prices.size - 2].close
        
        when {
            volumeRatio > 1.5 && priceChange > 0 -> score += 30 // 放量上涨
            volumeRatio > 1.5 && priceChange < 0 -> score -= 30 // 放量下跌
            volumeRatio < 0.7 -> score -= 10 // 缩量
        }
        
        return score.coerceIn(0.0, 100.0)
    }
    
    /**
     * 分析MACD
     * 返回分数：0-100
     */
    private fun analyzeMACD(indicators: TechnicalIndicators): Double {
        var score = 50.0
        
        if (indicators.macd != null && indicators.macdSignal != null && 
            indicators.macdHistogram != null) {
            
            // MACD金叉
            if (indicators.macd > indicators.macdSignal && indicators.macdHistogram > 0) {
                score += 30
            }
            // MACD死叉
            else if (indicators.macd < indicators.macdSignal && indicators.macdHistogram < 0) {
                score -= 30
            }
            
            // MACD在零轴上方
            if (indicators.macd > 0) {
                score += 20
            } else {
                score -= 10
            }
        }
        
        return score.coerceIn(0.0, 100.0)
    }
    
    /**
     * 计算目标价和止损价
     */
    private fun calculatePriceTargets(
        currentPrice: Double, 
        signalType: SignalType,
        indicators: TechnicalIndicators
    ): Pair<Double?, Double?> {
        
        return when (signalType) {
            SignalType.STRONG_BUY, SignalType.BUY -> {
                // 目标价：上涨5-10%
                val target = currentPrice * 1.08
                // 止损价：下跌3-5%
                val stopLoss = indicators.ma10?.let { 
                    minOf(currentPrice * 0.95, it * 0.98)
                } ?: (currentPrice * 0.95)
                
                Pair(target, stopLoss)
            }
            SignalType.SELL, SignalType.STRONG_SELL -> {
                // 目标价：下跌5-10%
                val target = currentPrice * 0.92
                // 止损价：上涨3-5%
                val stopLoss = currentPrice * 1.05
                
                Pair(target, stopLoss)
            }
            else -> Pair(null, null)
        }
    }
    
    /**
     * 生成推荐理由（基于真实日线数据）
     */
    private fun generateReason(
        signalType: SignalType,
        trendScore: Double,
        momentumScore: Double,
        overboughtOversoldScore: Double,
        indicators: TechnicalIndicators
    ): String {
        val reasons = mutableListOf<String>()
        
        // 添加日线分析说明
        reasons.add("【真实日线分析】")
        
        // 趋势分析
        if (trendScore > 70) {
            reasons.add("日线多头趋势明显，短中期向上")
        } else if (trendScore < 30) {
            reasons.add("日线空头趋势明显，短中期偏弱")
        }
        
        // 动量分析
        indicators.rsi?.let { rsi ->
            when {
                rsi < 30 -> reasons.add("日线RSI超卖(${"%.1f".format(rsi)})，短线反弹机会大")
                rsi > 70 -> reasons.add("日线RSI超买(${"%.1f".format(rsi)})，注意短期回调风险")
                rsi in 40.0..60.0 -> reasons.add("日线RSI处于健康区间(${"%.1f".format(rsi)})")
            }
        }
        
        // KDJ分析
        if (indicators.k != null && indicators.d != null) {
            if (indicators.k > indicators.d) {
                reasons.add("日线KDJ金叉，短期上涨动能强劲")
            } else if (indicators.k < indicators.d) {
                reasons.add("日线KDJ死叉，短期下跌压力较大")
            }
        }
        
        // MACD分析
        if (indicators.macd != null && indicators.macdSignal != null) {
            if (indicators.macd > indicators.macdSignal && indicators.macd > 0) {
                reasons.add("日线MACD零轴上方金叉，趋势向好")
            } else if (indicators.macd < indicators.macdSignal && indicators.macd < 0) {
                reasons.add("日线MACD零轴下方死叉，趋势偏弱")
            }
        }
        
        // 均线系统分析
        if (indicators.ma5 != null && indicators.ma10 != null && indicators.ma20 != null) {
            if (indicators.ma5 > indicators.ma10 && indicators.ma10 > indicators.ma20) {
                reasons.add("日线均线多头排列，建议持有或加仓")
            } else if (indicators.ma5 < indicators.ma10 && indicators.ma10 < indicators.ma20) {
                reasons.add("日线均线空头排列，建议减仓或观望")
            }
        }
        
        // 根据信号类型添加操作建议
        val actionAdvice = when (signalType) {
            SignalType.STRONG_BUY -> "建议明日开盘价附近分批买入，短线持有"
            SignalType.BUY -> "建议寻找合适时机买入"
            SignalType.SELL -> "建议寻找合适时机卖出"
            SignalType.STRONG_SELL -> "建议明日开盘价附近分批卖出"
            SignalType.HOLD -> "建议继续持有，等待更明确信号"
        }
        reasons.add(actionAdvice)
        
        return reasons.joinToString("；")
    }
    
    /**
     * 构建指标详情（真实日线）
     */
    private fun buildIndicatorDetails(
        indicators: TechnicalIndicators,
        prices: List<StockPrice>
    ): Map<String, String> {
        return buildMap {
            put("数据周期", "日线（真实数据）")
            indicators.ma5?.let { put("MA5", "%.2f".format(it)) }
            indicators.ma10?.let { put("MA10", "%.2f".format(it)) }
            indicators.ma20?.let { put("MA20", "%.2f".format(it)) }
            indicators.rsi?.let { put("RSI", "%.1f".format(it)) }
            indicators.k?.let { put("KDJ_K", "%.1f".format(it)) }
            indicators.d?.let { put("KDJ_D", "%.1f".format(it)) }
            indicators.macd?.let { put("MACD", "%.3f".format(it)) }
            
            val currentPrice = prices.last().close
            val prevPrice = prices[prices.size - 2].close
            val dayChange = ((currentPrice - prevPrice) / prevPrice * 100)
            put("昨日涨跌", "%.2f%%".format(dayChange))
            
            // 添加数据天数信息
            put("数据天数", "${prices.size}天")
            
            // 添加数据时间范围
            val firstDate = java.text.SimpleDateFormat("MM-dd", java.util.Locale.CHINA)
                .format(java.util.Date(prices.first().timestamp))
            val lastDate = java.text.SimpleDateFormat("MM-dd", java.util.Locale.CHINA)
                .format(java.util.Date(prices.last().timestamp))
            put("数据范围", "$firstDate ~ $lastDate")
        }
    }
    
    /**
     * 识别历史数据中的买卖点
     * 基于技术指标分析，标记出建议的买入和卖出时机
     */
    fun identifyTradingPoints(prices: List<StockPrice>): List<TradingPoint> {
        if (prices.size < 20) return emptyList()
        
        val tradingPoints = mutableListOf<TradingPoint>()
        
        // 需要足够的数据才能计算指标
        for (i in 20 until prices.size) {
            val subPrices = prices.subList(0, i + 1)
            val indicators = analyzer.calculateIndicators(subPrices)
            val currentPrice = subPrices.last()
            
            // 前一周期的指标（用于判断交叉）
            if (i >= 21) {
                val prevSubPrices = prices.subList(0, i)
                val prevIndicators = analyzer.calculateIndicators(prevSubPrices)
                
                // 判断买入信号
                val buySignal = checkBuySignal(indicators, prevIndicators, currentPrice)
                if (buySignal != null) {
                    tradingPoints.add(buySignal)
                }
                
                // 判断卖出信号
                val sellSignal = checkSellSignal(indicators, prevIndicators, currentPrice)
                if (sellSignal != null) {
                    tradingPoints.add(sellSignal)
                }
            }
        }
        
        return tradingPoints
    }
    
    /**
     * 检查买入信号
     */
    private fun checkBuySignal(
        indicators: TechnicalIndicators,
        prevIndicators: TechnicalIndicators,
        currentPrice: StockPrice
    ): TradingPoint? {
        val reasons = mutableListOf<String>()
        var score = 0
        
        // 1. MACD金叉（从下方穿过信号线）
        if (indicators.macd != null && indicators.macdSignal != null &&
            prevIndicators.macd != null && prevIndicators.macdSignal != null) {
            
            if (prevIndicators.macd < prevIndicators.macdSignal && 
                indicators.macd > indicators.macdSignal) {
                reasons.add("MACD金叉")
                score += 30
            }
        }
        
        // 2. KDJ金叉
        if (indicators.k != null && indicators.d != null &&
            prevIndicators.k != null && prevIndicators.d != null) {
            
            if (prevIndicators.k < prevIndicators.d && 
                indicators.k > indicators.d && 
                indicators.k < 30) {  // 在低位金叉
                reasons.add("KDJ低位金叉")
                score += 25
            }
        }
        
        // 3. RSI超卖反弹
        if (indicators.rsi != null && prevIndicators.rsi != null) {
            if (prevIndicators.rsi < 30 && indicators.rsi > 30) {
                reasons.add("RSI超卖反弹")
                score += 20
            }
        }
        
        // 4. 价格上穿MA均线
        if (indicators.ma5 != null && prevIndicators.ma5 != null) {
            val prevPrice = currentPrice.open  // 使用开盘价作为前一价格的近似
            if (prevPrice < prevIndicators.ma5 && currentPrice.close > indicators.ma5) {
                reasons.add("上穿MA5")
                score += 15
            }
        }
        
        // 5. 布林带下轨反弹
        if (indicators.bollLower != null) {
            if (currentPrice.low <= indicators.bollLower * 1.02 && 
                currentPrice.close > indicators.bollLower) {
                reasons.add("触及布林下轨反弹")
                score += 20
            }
        }
        
        // 如果得分超过40，认为是买入信号
        if (score >= 40 && reasons.isNotEmpty()) {
            return TradingPoint(
                timestamp = currentPrice.timestamp,
                price = currentPrice.close,
                type = PointType.BUY,
                reason = reasons.joinToString("、"),
                strength = score
            )
        }
        
        return null
    }
    
    /**
     * 检查卖出信号
     */
    private fun checkSellSignal(
        indicators: TechnicalIndicators,
        prevIndicators: TechnicalIndicators,
        currentPrice: StockPrice
    ): TradingPoint? {
        val reasons = mutableListOf<String>()
        var score = 0
        
        // 1. MACD死叉
        if (indicators.macd != null && indicators.macdSignal != null &&
            prevIndicators.macd != null && prevIndicators.macdSignal != null) {
            
            if (prevIndicators.macd > prevIndicators.macdSignal && 
                indicators.macd < indicators.macdSignal) {
                reasons.add("MACD死叉")
                score += 30
            }
        }
        
        // 2. KDJ死叉
        if (indicators.k != null && indicators.d != null &&
            prevIndicators.k != null && prevIndicators.d != null) {
            
            if (prevIndicators.k > prevIndicators.d && 
                indicators.k < indicators.d && 
                indicators.k > 70) {  // 在高位死叉
                reasons.add("KDJ高位死叉")
                score += 25
            }
        }
        
        // 3. RSI超买回落
        if (indicators.rsi != null && prevIndicators.rsi != null) {
            if (prevIndicators.rsi > 70 && indicators.rsi < 70) {
                reasons.add("RSI超买回落")
                score += 20
            }
        }
        
        // 4. 价格跌破MA均线
        if (indicators.ma5 != null && prevIndicators.ma5 != null) {
            val prevPrice = currentPrice.open
            if (prevPrice > prevIndicators.ma5 && currentPrice.close < indicators.ma5) {
                reasons.add("跌破MA5")
                score += 15
            }
        }
        
        // 5. 布林带上轨回落
        if (indicators.bollUpper != null) {
            if (currentPrice.high >= indicators.bollUpper * 0.98 && 
                currentPrice.close < indicators.bollUpper) {
                reasons.add("触及布林上轨回落")
                score += 20
            }
        }
        
        // 如果得分超过40，认为是卖出信号
        if (score >= 40 && reasons.isNotEmpty()) {
            return TradingPoint(
                timestamp = currentPrice.timestamp,
                price = currentPrice.close,
                type = PointType.SELL,
                reason = reasons.joinToString("、"),
                strength = score
            )
        }
        
        return null
    }
}

